package com.monitor.network;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 屏幕截图服务类
 * 定时捕获屏幕截图并上传到服务器
 */
public class ScreenCaptureService {
    // 使用ApiConfig获取API URL
    private static final long CAPTURE_INTERVAL_MINUTES = 1; // 截图间隔时间（分钟）
    private static final String LOCAL_SAVE_DIR = System.getProperty("user.home") + File.separator + "ScreenCaptures";
    
    private final ScheduledExecutorService scheduler;
    private final SimpleDateFormat dateFormat;
    private final Robot robot;
    private Long deviceId; // 设备ID，从注册信息中获取
    
    /**
     * 构造函数
     * 
     * @param deviceId 设备ID
     */
    public ScreenCaptureService(Long deviceId) {
        this.deviceId = deviceId;
        this.scheduler = Executors.newScheduledThreadPool(1);
        this.dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
        
        // 创建本地保存目录
        createLocalSaveDirectory();
        
        // 初始化Robot用于截屏
        try {
            this.robot = new Robot();
        } catch (AWTException e) {
            throw new RuntimeException("无法初始化屏幕截图功能", e);
        }
    }
    
    /**
     * 启动定时截屏服务
     */
    public void start() {
        // 立即执行一次截屏
        captureAndUpload();
        
        // 设置定时任务，每30分钟执行一次
        scheduler.scheduleAtFixedRate(
                this::captureAndUpload,
                CAPTURE_INTERVAL_MINUTES,
                CAPTURE_INTERVAL_MINUTES,
                TimeUnit.MINUTES
        );
        
        System.out.println("屏幕截图服务已启动，每" + CAPTURE_INTERVAL_MINUTES + "分钟截取一次屏幕");
    }
    
    /**
     * 停止定时截屏服务
     */
    public void stop() {
        scheduler.shutdown();
        System.out.println("屏幕截图服务已停止");
    }
    
    /**
     * 捕获屏幕截图并上传到服务器
     */
    private void captureAndUpload() {
        try {
            // 获取当前时间作为文件名
            String timestamp = dateFormat.format(new Date());
            String fileName = "screenshot_" + timestamp + ".png";
            String localFilePath = LOCAL_SAVE_DIR + File.separator + fileName;
            
            // 捕获屏幕截图
            BufferedImage screenshot = captureScreen();
            
            // 保存到本地
            File outputFile = new File(localFilePath);
            ImageIO.write(screenshot, "png", outputFile);
            
            // 上传到服务器
            uploadToServer(localFilePath, timestamp);
            
            System.out.println("截图已保存到: " + localFilePath + " 并上传到服务器");
        } catch (Exception e) {
            System.err.println("截图或上传过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 捕获整个屏幕的截图
     * 
     * @return 屏幕截图的BufferedImage对象
     */
    private BufferedImage captureScreen() {
        // 获取默认屏幕设备
        Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        // 捕获屏幕截图
        return robot.createScreenCapture(screenRect);
    }
    
    /**
     * 上传截图到服务器
     * 
     * @param imagePath 图片本地路径
     * @param timestamp 截图时间戳
     */
    private void uploadToServer(String imagePath, String timestamp) {
        try {
            // 获取API URL - 使用新的文件上传接口
            String apiUrl = ApiConfig.getScreenCaptureLogApiUrl() + "/upload";
            
            // 截屏时间 - 使用ISO 8601格式
            String captureTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date());
            
            System.out.println("开始上传截屏文件到: " + apiUrl);
            
            // 使用multipart/form-data格式上传文件
            String response = uploadFileWithMultipart(apiUrl, imagePath, deviceId, captureTime);
            
            System.out.println("服务器响应: " + response);
            
            // 解析响应
            JSONObject jsonResponse = JSON.parseObject(response);
            int code = jsonResponse.getIntValue("code");
            
            if (code == 200) {
                System.out.println("截图文件上传成功");
            } else {
                System.err.println("上传截图失败，错误码: " + code + ", 消息: " + jsonResponse.getString("msg"));
            }
        } catch (Exception e) {
            System.err.println("上传截图到服务器时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 使用multipart/form-data格式上传文件
     * 
     * @param apiUrl 上传接口URL
     * @param filePath 本地文件路径
     * @param deviceId 设备ID
     * @param captureTime 截屏时间
     * @return 服务器响应
     * @throws IOException 如果发生网络错误
     */
    private String uploadFileWithMultipart(String apiUrl, String filePath, Long deviceId, String captureTime) throws IOException {
        String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
        String CRLF = "\r\n";
        
        URL url = new URL(apiUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        
        try {
            // 设置请求属性
            connection.setRequestMethod("POST");
            connection.setConnectTimeout(10000); // 增加超时时间
            connection.setReadTimeout(30000);    // 增加读取超时时间
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
            connection.setRequestProperty("Accept", "application/json");
            
            // 构建multipart数据
            try (OutputStream os = connection.getOutputStream();
                 PrintWriter writer = new PrintWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8), true)) {
                
                // 添加设备ID参数
                writer.append("--" + boundary).append(CRLF);
                writer.append("Content-Disposition: form-data; name=\"deviceId\"").append(CRLF);
                writer.append("Content-Type: text/plain; charset=UTF-8").append(CRLF);
                writer.append(CRLF);
                writer.append(deviceId.toString()).append(CRLF);
                writer.flush();
                
                // 添加截屏时间参数
                writer.append("--" + boundary).append(CRLF);
                writer.append("Content-Disposition: form-data; name=\"captureTime\"").append(CRLF);
                writer.append("Content-Type: text/plain; charset=UTF-8").append(CRLF);
                writer.append(CRLF);
                writer.append(captureTime).append(CRLF);
                writer.flush();
                
                // 添加文件
                File file = new File(filePath);
                writer.append("--" + boundary).append(CRLF);
                writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"").append(CRLF);
                writer.append("Content-Type: image/png").append(CRLF);
                writer.append("Content-Transfer-Encoding: binary").append(CRLF);
                writer.append(CRLF);
                writer.flush();
                
                // 写入文件内容
                try (FileInputStream fis = new FileInputStream(file)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = fis.read(buffer)) != -1) {
                        os.write(buffer, 0, bytesRead);
                    }
                    os.flush();
                }
                
                writer.append(CRLF);
                writer.append("--" + boundary + "--").append(CRLF);
                writer.flush();
            }
            
            // 获取响应
            int responseCode = connection.getResponseCode();
            InputStream inputStream = (responseCode == HttpURLConnection.HTTP_OK) 
                ? connection.getInputStream() 
                : connection.getErrorStream();
                
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                
                if (responseCode != HttpURLConnection.HTTP_OK) {
                    throw new IOException("HTTP错误代码: " + responseCode + ", 响应: " + response.toString());
                }
                
                return response.toString();
            }
        } finally {
            connection.disconnect();
        }
    }
    
    /**
     * 创建本地保存目录
     */
    private void createLocalSaveDirectory() {
        Path dirPath = Paths.get(LOCAL_SAVE_DIR);
        if (!Files.exists(dirPath)) {
            try {
                Files.createDirectories(dirPath);
                System.out.println("创建截图保存目录: " + LOCAL_SAVE_DIR);
            } catch (IOException e) {
                System.err.println("无法创建截图保存目录: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
}